﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using OfficeOpenXml;

namespace Critr
{
    class LogParser
    {
        public static LogSheet ParseExcelLog(String filename)
        {
            FileInfo workFile = new FileInfo(filename);

            using (ExcelPackage pck = new ExcelPackage(workFile))
            {
                ExcelWorksheet worksheet = pck.Workbook.Worksheets[1];

                LogSheet retLogSheet = GetHeaders(worksheet);

                retLogSheet.Entries = GetEntries(worksheet);

                return retLogSheet;
            }
        }

        private static LogSheet GetHeaders(ExcelWorksheet ws)
        {
            LogSheet ls = new LogSheet();

            /* Grab easy to parse cells */
            ls.Programmer = ws.Cells["C3"].Value.ToString();
            ls.NameOfShow = ws.Cells["C4"].Value.ToString();
            ls.Guest = ws.Cells["E4"].Value.ToString();
            ls.Time = ws.Cells["I4"].Value.ToString();

            /* Pick out description */
            string dirtyDescription = ws.Cells["A5"].Value.ToString();
            Regex descriptionRegex = new Regex(":\\s*(.+)");
            Match match = descriptionRegex.Match(dirtyDescription);
            if (match.Success)
            {
                ls.Description = match.Groups[1].Value;
            }
            else
            {
                ls.Description = dirtyDescription;
            }

            /* Pick out broadcast date */
            try
            {
                DateTime.TryParse(ws.Cells["I3"].Value.ToString(), out ls.BroadcastDate);
            }
            catch (ArgumentOutOfRangeException e)
            {
                // implement error message
            }

            return ls;
        }

        private static List<LogEntry> GetEntries(ExcelWorksheet ws)
        {
            List<LogEntry> retLogEntryList = new List<LogEntry>();

            for (int i = 11; i < 72; i++)
            {
                if (ws.Cells[i, 2].Value != null && ws.Cells[i, 3].Value != null)    // If artist or title is NOT null
                {
                    LogEntry retLogEntry = new LogEntry();

                    retLogEntry.Artist = ws.Cells[i, 2].Value.ToString();
                    retLogEntry.Title = ws.Cells[i, 3].Value.ToString();
                    retLogEntry.Album = ws.Cells[i, 4].Value.ToString() ?? "";
                    retLogEntry.Duration = (ws.Cells[i, 5].Value == null) ? default(double) : (double)ws.Cells[i, 5].Value; // Null coalescing doesn't work with doubles?

                    try
                    {
                        retLogEntry.Log = Convert.ToInt32(ws.Cells[i, 7].Value.ToString());
                    }
                    catch (InvalidCastException e)
                    {
                        // implement error message
                        retLogEntry.Log = 12;
                    }

                    retLogEntry.Cancon = (ws.Cells[i, 8].Value == null) ? false : true;
                    retLogEntry.Hit = (ws.Cells[i, 9].Value == null) ? false : true;
                    retLogEntry.Chart = (ws.Cells[i, 10].Value == null) ? false : true;

                    /* Only set Chart from xlsx if Chartable is checked */
                    retLogEntry.Class = (retLogEntry.Chart) ? ws.Cells[i, 11].Value.ToString() : "";

                    retLogEntryList.Add(retLogEntry);
                }
            }

            if (retLogEntryList.Count == 0)
            {
                // implement error message
            }

            return retLogEntryList;
        }
    }
}
